﻿using Microsoft.VisualStudio.TextTemplating;
using Microsoft.Data.Schema.SchemaModel;
using Microsoft.VisualStudio.Data.Schema.Package.Project;
using System;
using System.Globalization;
using System.Reflection;
using System.Collections.Generic;

namespace TFDP.Common.T4
{
    public abstract class DatabaseTemplate<T> : TextTransformation where T : IModelElement
    {
        public T Element { get; set; }
        public bool IsCanceled { get; private set; }

        private IDatabaseNode node;

        public IDatabaseNode Node
        {
            get { return this.node; }
            set { this.node = value; }
        }

        public ModelStore Model
        {
            get
            {
                if (Element != null)
                    return Element.Model;
                else
                    return null;
            }
        }
        
        private global::Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost templatingHost;
        public global::Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost TemplatingHost
        {
            get
            {
                return this.templatingHost;
            }
            set
            {
                this.templatingHost = value;
            }
        }

        private List<GeneratedArtifact> artifacts;

        [Obsolete("Use Host.Artifacts instead")]
        public IEnumerable<GeneratedArtifact> Artifacts
        {
            get { return artifacts.AsReadOnly(); }
        }

        [Obsolete("Use Host.AddArtifact instead")]
        public void AddArtifact(GeneratedArtifact artifact)
        {
            if (artifact == null)
                throw new ArgumentNullException("artifact");

            artifacts.Add(artifact);
        }

        private ToStringInstanceHelper tshInstance;
        public ToStringInstanceHelper ToStringHelper
        {
            get { return tshInstance; }
        }

        public override void Initialize()
        {
            tshInstance = new ToStringInstanceHelper();

            base.Initialize();
            
            this.artifacts = new List<GeneratedArtifact>();
            this.IsCanceled = false;
            this.Errors.Clear();
            this.GenerationEnvironment.Clear();
        }

        public void CancelGeneration()
        {
            IsCanceled = true;
            throw new GenerationCanceledException();
        }

        public class ToStringInstanceHelper
        {
            // Fields
            private IFormatProvider formatProviderField = CultureInfo.InvariantCulture;

            // Methods
            public string ToStringWithCulture(object objectToConvert)
            {
                if (objectToConvert == null)
                {
                    throw new ArgumentNullException("objectToConvert");
                }
                MethodInfo method = objectToConvert.GetType().GetMethod("ToString", new Type[] { typeof(IFormatProvider) });
                if (method == null)
                {
                    return objectToConvert.ToString();
                }
                return (string)method.Invoke(objectToConvert, new object[] { this.formatProviderField });
            }

            // Properties
            public IFormatProvider FormatProvider
            {
                get
                {
                    return this.formatProviderField;
                }
                set
                {
                    if (value != null)
                    {
                        this.formatProviderField = value;
                    }
                }
            }
        }
    }
}
